package com.indusfo.spc.client.service.impl;

import com.indusfo.spc.client.mapper.*;
import com.indusfo.spc.client.pojo.WorkStation;
import com.indusfo.spc.client.service.ClientAnoService;
import com.indusfo.spc.client.service.WorkStationService;
import com.indusfo.spc.enums.JobBookEnum;
import com.indusfo.spc.mapper.ClientClasseWorkMapper;
import com.indusfo.spc.mapper.OrderMapper;
import com.indusfo.spc.pojo.*;
import com.indusfo.spc.service.BarCodeRules;
import com.indusfo.spc.service.RuleService;
import com.indusfo.spc.untlis.InstantUtil;
import com.indusfo.spc.untlis.JsonXMLUtils;
import com.indusfo.spc.untlis.StringUtils;
import com.indusfo.spc.untlis.TokenUtil;
import com.indusfo.spc.vo.JSONObject;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.Month;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author chenm
 * @create 2019-12-04 21:03
 */
@Service
public class WorkStationServiceImpl implements WorkStationService {

  @Resource
  private OrderMapper orderMapper;

  @Resource
  private ClientOrderMapper clientOrderMapper;

  @Resource
  private ClientBatchMapper clientBatchMapper;

  @Resource
  private ClientMatMapper clientMatMapper;

  @Resource
  private ClientRuleMapper clientRuleMapper;

  @Resource
  private ClientOrderFlowMapper clientOrderFlowMapper;

  @Resource
  private ClientOrderTechMapper clientOrderTechMapper;

  @Resource
  private ClientBatchFlowFinishMapper clientBatchFlowFinishMapper;

  @Resource
  private ClientPalletMapper clientPalletMapper;

  @Resource
  private BarCodeRules barCodeRules;

  @Resource
  private ClientOrderStationMapper clientOrderStationMapper;

  @Resource
  private ClientProMapper clientProMapper;

  @Resource
  private ClientAnoService clientAnoService;

  @Resource
  private ClientClasseWorkMapper clientClasseWorkMapper;

  @Resource
  private ClientClasseMapper clientClasseMapper;

  @Resource
  private RuleService ruleService;

  @Override
  @Transactional
  public JSONObject firstJobWork(Map<String, Object> models)throws Exception {
    String userIdStr =JsonXMLUtils.obj2json(models.get("userId"));
    String stationIdStr = JsonXMLUtils.obj2json(models.get("stationId"));
    String batchCode =JsonXMLUtils.obj2json(models.get("batchCode")).replace("\"", "");
    String palletCode = JsonXMLUtils.obj2json(models.get("palletCode")).replace("\"", "");
    String orderIdStr = JsonXMLUtils.obj2json(models.get("orderId"));
    String type = JsonXMLUtils.obj2json(models.get("type"));
    String classeIdStr = JsonXMLUtils.obj2json(models.get("classeId"));
    String isOffLineStationStr = JsonXMLUtils.obj2json(models.get("isOffLineStation")).replace("\"", "");
    if(StringUtils.isBlank(type) || type.equals("null")){
      return JSONObject.build(JSONObject.ERROR,"模式类型不能为空");
    }
    if(StringUtils.isBlank(userIdStr) || userIdStr.equals("null")){
      return JSONObject.build(JSONObject.ERROR, "作业人员不能为空");
    }
    if(StringUtils.isBlank(stationIdStr) || stationIdStr.equals("null")){
      return JSONObject.build(JSONObject.ERROR,"工位不能为空");
    }
    if(StringUtils.isBlank(orderIdStr) || orderIdStr.equals("null")){
      return JSONObject.build(JSONObject.ERROR,"订单不能为空");
    }
    if(StringUtils.isBlank(classeIdStr) || classeIdStr.equals("null")){
      return JSONObject.build(JSONObject.ERROR,"班次不能为空");
    }
    Boolean isOffLineStation = Boolean.valueOf(isOffLineStationStr);
    Integer userId = Integer.valueOf(userIdStr);
    Integer stationId = Integer.valueOf(stationIdStr);
    Integer orderId = Integer.valueOf(orderIdStr);
    Integer classeId = Integer.valueOf(classeIdStr);
    JobBookEnum[] jobBookEnums = JobBookEnum.values();
    Classe classe = clientClasseMapper.getById(classeId);
    if(null == classe){
      return JSONObject.build(JSONObject.ERROR, "没有查到班次信息");
    }
    if(classe.getDataState().equals(3)){
      return JSONObject.build(JSONObject.ERROR, "该班次信息被停用了");
    }
    ClasseWork classeWork = clientClasseWorkMapper.onLineByClasseId(classeId);
    if(null ==classeWork){
      return JSONObject.build(JSONObject.ERROR, "该班次没有开工");
    }

    JobBookEnum jobBookEnum =null;

    for(JobBookEnum bookEnum : jobBookEnums){
      if(bookEnum.getValue().equals(type)){
        jobBookEnum = bookEnum;
      }
    }
    switch (jobBookEnum){
      case 自动创建批次一次完工:
        return oneJobBook(userId,stationId,orderId,true,isOffLineStation,classeId,classeWork);
      case 自动创建批次二次完工:
        return twoJobBook(userId,stationId,orderId,batchCode,false,isOffLineStation,classeId,classeWork);
      case 扫描托盘创建批次一次完工:
        return threeJobBook(userId,stationId,orderId,palletCode,true,isOffLineStation,classeId,classeWork);
      case 扫描托盘创建批次二次完工:
        return fourJobBook(userId,stationId,orderId,batchCode,palletCode,false,isOffLineStation,classeId,classeWork);
      case 扫描现有托盘创建批次一次完工:
        return fiveJobBook(userId,stationId,orderId,batchCode,true,isOffLineStation,classeId,classeWork);
      case 扫描现有托盘创建批次二次完工:
        return fiveJobBook(userId,stationId,orderId,batchCode,false,isOffLineStation,classeId,classeWork);
      case 扫描现有托盘创建批次并绑定托盘一次完工:
        return sevenJobBook(userId,stationId,orderId,batchCode,palletCode,true,isOffLineStation,classeId,classeWork);
      case 扫描现有托盘创建批次并绑定托盘二次完工:
        return eightJobBook(userId,stationId,orderId,batchCode,palletCode,false,isOffLineStation,classeId,classeWork);
      default:
        return JSONObject.build(JSONObject.ERROR,"不存在其他模式");
    }
  }


  /* *
   * 模式一（flag判断是否一次完工）
   */
  public JSONObject oneJobBook(Integer userId, Integer stationId, Integer orderId,Boolean flag,Boolean isOffLineStation,Integer classeId,ClasseWork classeWork) {
    Order order = clientOrderMapper.selectByOrderId(orderId);
    if(null == order){
      return JSONObject.build(JSONObject.ERROR, "无此任务单信息");
    }
    if(order.getDataState().equals(3)){
      return JSONObject.build(JSONObject.ERROR, "任务单已停产，不可投产");
    }
    if(order.getExecuteStateId().equals(4)){
      return JSONObject.build(JSONObject.ERROR, "任务单暂停中，不可投产");
    }
    Mat mat = clientMatMapper.selectMatByMatId(order.getMatId());
    if(null == mat){
      return JSONObject.build(JSONObject.ERROR, "无此产品信息信息");
    }
    if(mat.getDataState().equals(3)){
      return JSONObject.build(JSONObject.ERROR, "产品已被停用，不可投产");
    }
    Rule rule = clientRuleMapper.selectByRuleId(mat.getRuleId());
    if(null == rule){
      return JSONObject.build(JSONObject.ERROR, "产品没有条码规则，不可投产");
    }
    if(rule.getDataState().equals(3)){
      return JSONObject.build(JSONObject.ERROR, "条码规则已被停用，不可投产");
    }
    OrderTech orderTech =  clientOrderTechMapper.selectByOrderTechId(order.getOrderTechId());
    if(null == orderTech ){
      return JSONObject.build(JSONObject.ERROR, "产品没有任务单流程，不可投产");
    }
    List<OrderFlow> orderFlows = clientOrderFlowMapper.selectByOrderTechId(orderTech.getOrderTechId());
    if(orderFlows.isEmpty() ){
      return JSONObject.build(JSONObject.ERROR, "产品没有任务单流程，不可投产");
    }
    Integer commissioning = clientBatchMapper.commissioning(orderId);
    if(commissioning >= order.getPlanNum()){
      return JSONObject.build(JSONObject.ERROR, "任务单已满，不可创建投产");
    }
    List<Integer> orderFlowIdArr = orderFlows.stream().map(OrderFlow::getOrderFlowId).collect(Collectors.toList());
    /**
     * 查询工序流程的首工位
     * */
    List<Integer> orderFlowIds = new ArrayList<>();
    orderFlowIds.add(orderFlowIdArr.get(0));
    List<Integer> stationIds = clientOrderStationMapper.selectStationIdByOrderFlowIdsAndStationId(orderFlowIds,stationId);
    if(stationIds.isEmpty()){
      return JSONObject.build(JSONObject.ERROR, "本工位不可创建批号，请检查任务单流程");
    }
    /*
     * 生成条码
     * */
    Date date = new Date();
    List<String> barCodes =  ruleService.batchRule(orderId,1);
    if(barCodes.isEmpty()){
      return JSONObject.build(JSONObject.ERROR, "创建批号失败");
    }
    String barCode = barCodes.get(0);
    /*
     * 生成批次号
     * */
    Batch batch = new Batch();
    batch.setBatchCode(barCode);//批次号
    batch.setUserId(userId);  // 创建人
    batch.setProductDate(date);//生产时间
    batch.setStationId(stationId);//开工工位
    batch.setClasseId(classeId);//开工班次
    batch.setClasseDate(classeWork.getLoginDate());//开工班次时间
    batch.setOrderId(orderId);
    batch.setPrintStateId(1);
    batch.setProductStateId(2);//1待投产，2投产中，3部分投产，4完工，5报废
    
    if(order.getActualStartDate() == null) {
    	order.setActualStartDate(date);
    }
    if(order.getExecuteStateId().equals(2)){
      order.setExecuteStateId(3);//1待发布，2已发布，3生产中，4暂停，5完工
      clientOrderMapper.updateOrder(order);
    }

    /**
     *  首工序一次完工 记录当前工序为下次工序，否则是自己
     * */
    if(flag){
      if(orderFlowIdArr.size()>1){
        /**
         * 如果含有下道工序
         * */
        batch.setOrderFlowId(orderFlowIdArr.get(1));
        batch.setOrderFlowStateId(1);//1未完工，2已投产，3已完工，4跳序完工
      }else{
        if (isOffLineStation) {
          // 判断是否已经插入维修工序
          Integer proTypeId = clientProMapper.queryNextProTypeIdByBatchId(batch.getBatchId());
          if (null != proTypeId && proTypeId == 1) {
            clientAnoService.insertRepair(batch.getBatchId(), batch.getOrderId(), orderTech.getOrderTechId(), orderFlowIdArr.get(0), userId);
          }
        }
        batch.setEndClasseDate(classeWork.getLogoutDate());//完工班次时间
        batch.setEndClasseId(classeId);//完工班次
        batch.setEndStationId(stationId);//完工工位
        batch.setFinshDate(date);//完工时间
        batch.setOrderFlowId(orderFlowIdArr.get(0));
        batch.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
        batch.setProductStateId(4);//1待投产，2投产中，3部分投产，4完工，5报废
        if(clientBatchMapper.finished(orderId,null) == order.getPlanNum() - 1){ //出自己之外的工序都完工了
          order.setExecuteStateId(5);//1待发布，2已发布，3生产中，4暂停，5完工
          orderMapper.updateOrder(order);
        }
      }
    }else{
      batch.setOrderFlowId(orderFlowIdArr.get(0));
      batch.setOrderFlowStateId(2);//1未完工，2已投产，3已完工，4跳序完工
    }
    batch.setOrderTechId(orderTech.getOrderTechId());// 任务单流程赋值给批次流程
    batch.setUserId(Integer.parseInt(TokenUtil.getTokenUserId()));
    clientBatchMapper.insertBatch(batch);
    BatchFlowFinish batchFlowFinish = new BatchFlowFinish();
    batchFlowFinish.setSerialNum(orderFlows.get(0).getSerialNum());
    batchFlowFinish.setBatchId(batch.getBatchId());
    batchFlowFinish.setStationId(stationId);
    batchFlowFinish.setUserId(userId);
    batchFlowFinish.setStartDate(date);
    batchFlowFinish.setOrderFlowStateId(2);
    batchFlowFinish.setProId(orderFlows.get(0).getProId());
    batchFlowFinish.setClasseId(classeId);
    if(flag){
      /**
       * 一次完工记录报工时间，否则不记录
       * */
      batchFlowFinish.setOrderFlowStateId(3);
      batchFlowFinish.setEndDate(date);
    }
    clientBatchFlowFinishMapper.insertBatchFlowFinish(batchFlowFinish);
    Map<String,Object> map = new HashedMap();
    map.put("barCode",barCode);
    map.put("batchId",batch.getBatchId());
    map.put("serialNum",orderFlows.get(0).getSerialNum());
    map.put("currentOrderFlowId",orderFlowIdArr.get(0));
    map.put("proId",orderFlows.get(0).getProId());
    map.put("matId",order.getMatId());
    if(flag){
      map.put("finish",1);
      return JSONObject.build(JSONObject.SUCCESS,barCode + "创建成功并完工作业",map);
    }else{
      map.put("finish",0);
      return JSONObject.build(JSONObject.SUCCESS,barCode + "创建成功并开工作业",map);
    }
  }

  /*
   * 模式二(一次报工为否)
   * */
  private JSONObject twoJobBook(Integer userId, Integer stationId, Integer orderId, String batchCode,Boolean flag,Boolean isOffLineStation,Integer classeId,ClasseWork classeWork) {
    if(StringUtils.isBlank(batchCode) || batchCode.equals("null")){
      return oneJobBook(userId,stationId,orderId,flag,isOffLineStation,classeId,classeWork);
    }else {
      Batch batch = clientBatchMapper.selectByBatchCode(batchCode);
      if (null == batch) {
        return JSONObject.build(JSONObject.ERROR, batchCode + "批号不存在");
      }
      Order order = clientOrderMapper.selectByOrderId(orderId);
      if (order.getDataState().equals(3)) {
        return JSONObject.build(JSONObject.ERROR, "任务单已停产，不可投产");
      }
      if (order.getExecuteStateId().equals(4)) {
        return JSONObject.build(JSONObject.ERROR, "任务单暂停中，不可投产");
      }

      /* *
       * 查询当前工序
       * */
      OrderFlow currentOrderFlow = clientOrderFlowMapper.selectByOrderFlowId(batch.getOrderFlowId());
      OrderTech orderTech = clientOrderTechMapper.selectByOrderTechId(order.getOrderTechId());
      List<Integer> orderFlowIds = new ArrayList<>();
      orderFlowIds.add(currentOrderFlow.getOrderFlowId());
      List<OrderStation> orderStations = clientOrderStationMapper.selectByOrderFlowIdsAndStationId(orderFlowIds, stationId);
      if (orderStations.isEmpty()) {
        return JSONObject.build(JSONObject.ERROR, batchCode + "批号当前工序为[" + currentOrderFlow.getProName() + "]工序不在本工位作业");
      }
      /**
       * 根据当前工序查询下道工序
       * */
      List<OrderFlow> nextOrderFlows = clientOrderFlowMapper.nextOrderFlowByCurrentOrderFlowId(currentOrderFlow.getOrderFlowId(), orderTech.getOrderTechId());

      Map<String, Object> map = new HashedMap();
      String msg = "";
      BatchFlowFinish batchFlowFinish = clientBatchFlowFinishMapper.selectByBatchIdAndSerialNum(batch.getBatchId(), currentOrderFlow.getSerialNum());
      Date date = new Date();
      if(order.getActualStartDate() == null) {
        	order.setActualStartDate(date);
        }
      /*
      batchFlowFinish.setEndDate(date);
      batchFlowFinish.setOrderFlowStateId(3);
      */
      if (nextOrderFlows.isEmpty()) {
        batch.setOrderFlowId(currentOrderFlow.getOrderFlowId());
        batch.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
        batch.setFinshDate(date);
        batch.setEndClasseDate(date);
        batch.setEndClasseId(classeId);
        batch.setEndStationId(stationId);
        if (clientBatchMapper.finished(orderId, null) == order.getPlanNum() - 1) { //出自己之外的工序都完工了
          order.setExecuteStateId(5);
          orderMapper.updateOrder(order);
          batch.setProductStateId(4);//1待投产，2投产中，3部分投产，4完工，5报废
        }
      } else {
        batch.setOrderFlowId(nextOrderFlows.get(0).getOrderFlowId());
        batch.setOrderFlowStateId(1);//1未完工，2已投产，3已完工，4跳序完工
      }
      clientBatchFlowFinishMapper.updateBatchFlowFinish(batchFlowFinish);
      map.put("finish", 1);
      msg = "批号完工作业";
      batch.setStationId(stationId);
      batch.setUserId(userId);
      clientBatchMapper.updateBatch(batch);

      map.put("currentOrderFlowId",batch.getOrderFlowId());
      map.put("barCode",batchCode);
      map.put("batchId",batch.getBatchId());
      map.put("serialNum",currentOrderFlow.getSerialNum());
      map.put("proId",currentOrderFlow.getProId());
      map.put("matId",order.getMatId());
      return JSONObject.build(JSONObject.SUCCESS,batchCode + msg,map);
    }
  }


  /**
   *
   * 模式三（一次报工为是）
   */

  public JSONObject threeJobBook(Integer userId, Integer stationId,Integer orderId, String palletCode,Boolean flag,Boolean isOffLineStation,Integer classeId,ClasseWork classeWork) {
    if(StringUtils.isEmpty(palletCode) || palletCode.equals("null")){
      return JSONObject.build(JSONObject.ERROR,"托盘号不可为空");
    }
    Pallet pallet = clientPalletMapper.selectByPallentCode(palletCode);
    if(null == pallet){
      return JSONObject.build(JSONObject.ERROR, "查无此托盘号，不可投产");
    }
    if(pallet.getDataState().equals(3)){
      return JSONObject.build(JSONObject.ERROR, "托盘号已被禁用，不可投产");
    }
    JSONObject jsonObject = oneJobBook(userId,stationId,orderId,flag,isOffLineStation,classeId,classeWork);
    if(jsonObject.getStatus().equals(JSONObject.SUCCESS)){
      Map<String,Object> map = (Map<String, Object>) jsonObject.getData();
      Integer batchId = (Integer) map.get("batchId");
      pallet.setBatchId(batchId);
      clientPalletMapper.updatePallent(pallet);
    }
    return jsonObject;
  }

  /**
   *
   * 模式四（一次报工为否）
   */
  public JSONObject fourJobBook(Integer userId, Integer stationId, Integer orderId, String batchCode, String palletCode,Boolean flag,Boolean isOffLineStation,Integer classeId,ClasseWork classeWork) {
    if(!StringUtils.isEmpty(batchCode) && !batchCode.equals("null")){
      return twoJobBook(userId,stationId,orderId,batchCode,flag,isOffLineStation,classeId,classeWork);
    }
    if(!StringUtils.isEmpty(palletCode) && !palletCode.equals("null")){
      Pallet pallet = clientPalletMapper.selectByPallentCode(palletCode);
      if(null == pallet){
        return JSONObject.build(JSONObject.ERROR, "查无此托盘号，不可投产");
      }
      if(pallet.getDataState().equals(3)){
        return JSONObject.build(JSONObject.ERROR, "托盘号已被禁用，不可投产");
      }
      if(null == pallet.getBatchId()){
        JSONObject jsonObject = oneJobBook(userId,stationId,orderId,flag,isOffLineStation,classeId,classeWork);
        if(jsonObject.getStatus().equals(JSONObject.SUCCESS)){
          Map<String,Object> map = (Map<String, Object>) jsonObject.getData();
          Integer batchId = (Integer) map.get("batchId");
          pallet.setBatchId(batchId);
          clientPalletMapper.updatePallent(pallet);
          jsonObject.setMsg(jsonObject.getMsg()+"("+palletCode+")");
        }
        return jsonObject;
      }else{
        Batch batch = clientBatchMapper.selectByBatchId(pallet.getBatchId());
        /* *
         * 查询当前工序
         * */
        OrderFlow currentOrderFlow = clientOrderFlowMapper.selectByOrderFlowId(batch.getOrderFlowId());
        List<Integer> orderFlowIds = new ArrayList<>();
        orderFlowIds.add(currentOrderFlow.getOrderFlowId());
        List<OrderStation> orderStations = clientOrderStationMapper.selectByOrderFlowIdsAndStationId(orderFlowIds,stationId);
        if(orderStations.isEmpty()){ //托盘当前绑定的不是首工位
          JSONObject jsonObject = oneJobBook(userId,stationId,orderId,flag,isOffLineStation,classeId,classeWork);
          if(jsonObject.getStatus().equals(JSONObject.SUCCESS)){
            Map<String,Object> map = (Map<String, Object>) jsonObject.getData();
            Integer batchId = (Integer) map.get("batchId");
            pallet.setBatchId(batchId);
            clientPalletMapper.updatePallent(pallet);
            jsonObject.setMsg(jsonObject.getMsg()+"("+palletCode+")");
          }
          return jsonObject;
        }else{  //绑定的是本工位
          JSONObject jsonObject = twoJobBook(userId,stationId,orderId,batch.getBatchCode(),true,isOffLineStation,classeId,classeWork);
          jsonObject.setMsg(jsonObject.getMsg()+"("+palletCode+")");
          return jsonObject;
        }
      }
    }
    return JSONObject.build(JSONObject.ERROR,"批号和托盘不可同时为空或同时存在");
  }

  /**
   *
   * 模式五（一次报工为是）+模式六（一次报工为否）
   */
  private JSONObject fiveJobBook(Integer userId, Integer stationId, Integer orderId, String batchCode,Boolean flag,Boolean isOffLineStation,Integer classeId,ClasseWork classeWork) {
    if(StringUtils.isEmpty(batchCode) || batchCode.equals("null")){
      return JSONObject.build(JSONObject.ERROR,"批号不可为空");
    }
    Order order = clientOrderMapper.selectByOrderId(orderId);
    if(null == order){
      return JSONObject.build(JSONObject.ERROR, "无此任务单信息");
    }
    if(order.getDataState().equals(3)){
      return JSONObject.build(JSONObject.ERROR, "任务单已被停用，不可投产");
    }
    if(order.getExecuteStateId().equals(4)){
      return JSONObject.build(JSONObject.ERROR, "任务单暂停中，不可投产");
    }
    Mat mat = clientMatMapper.selectMatByMatId(order.getMatId());
    if(mat == null){
      return JSONObject.build(JSONObject.ERROR, "无此产品信息信息");
    }
    if(mat.getDataState().equals(3)){
      return JSONObject.build(JSONObject.ERROR, "产品已被停用，不可投产");
    }
    OrderTech orderTech =  clientOrderTechMapper.selectByOrderTechId(order.getOrderTechId());
    if(null == orderTech ){
      return JSONObject.build(JSONObject.ERROR, "产品没有任务单流程，不可投产");
    }
    List<OrderFlow> orderFlows = clientOrderFlowMapper.selectByOrderTechId(orderTech.getOrderTechId());
    if(orderFlows.isEmpty() ){
      return JSONObject.build(JSONObject.ERROR, "产品没有任务单流程，不可投产");
    }
    Integer commissioning = clientBatchMapper.commissioning(orderId);
    if(commissioning >= order.getPlanNum()){
      return JSONObject.build(JSONObject.ERROR, "任务单已满，不可创建投产");
    }
    List<Integer> orderFlowIdArr = orderFlows.stream().map(OrderFlow::getOrderFlowId).collect(Collectors.toList());
    /**
     * 查询工序流程的首工位
     * */
    List<Integer> orderFlowIds = new ArrayList<>();
    orderFlowIds.add(orderFlowIdArr.get(0));
    List<Integer> stationIds = clientOrderStationMapper.selectStationIdByOrderFlowIdsAndStationId(orderFlowIds,stationId);
    if(stationIds.isEmpty()){
      return JSONObject.build(JSONObject.ERROR, "本工位不可创建批号，请检查任务单流程");
    }
    Date date = new Date();
    if(order.getActualStartDate() == null) {
      	order.setActualStartDate(date);
      }
    Batch batch = clientBatchMapper.selectByBatchCode(batchCode);
    Map<String,Object> map = new HashedMap();
    //没有创建过批次
    if(batch == null){
      batch = new Batch();
      batch.setBatchCode(batchCode);//批次号
      batch.setUserId(userId);// 创建人
      batch.setProductDate(date);//生产时间
      batch.setStationId(stationId);//开工工位
      batch.setClasseId(classeId);//开工班次
      batch.setClasseDate(classeWork.getLoginDate());//开工班次时间
      batch.setOrderId(orderId);
      batch.setPrintStateId(1);
      batch.setProductStateId(2);//1待投产，2投产中，3部分投产，4完工，5报废

      if(order.getExecuteStateId().equals(2)){
        order.setExecuteStateId(3);//1待发布，2已发布，3生产中，4暂停，5完工
        clientOrderMapper.updateOrder(order);
      }
      //一次报工的话要判断是否含有其他工序
      if(flag){
        if(orderFlowIdArr.size()>1){
          /**
           * 如果含有下道工序
           * */
          batch.setOrderFlowId(orderFlowIdArr.get(1));
          batch.setOrderFlowStateId(1);//1未完工，2已投产，3已完工，4跳序完工
        }else{
          batch.setEndClasseDate(classeWork.getLogoutDate());//完工班次时间
          batch.setEndClasseId(classeId);//完工班次
          batch.setEndStationId(stationId);//完工工位
          batch.setFinshDate(date);//完工时间
          batch.setOrderFlowId(orderFlowIdArr.get(0));
          batch.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
          batch.setProductStateId(4);//1待投产，2投产中，3部分投产，4完工，5报废
          if(clientBatchMapper.finished(orderId,null) == order.getPlanNum() - 1){ //出自己之外的工序都完工了
            order.setExecuteStateId(5);//1待发布，2已发布，3生产中，4暂停，5完工
            clientOrderMapper.updateOrder(order);
          }
        }
      }else{
        batch.setOrderFlowId(orderFlowIdArr.get(0));
        batch.setOrderFlowStateId(2);//1未完工，2已投产，3已完工，4跳序完工
      }
      OrderFlow currentOrderFlow = orderFlows.get(0);
      batch.setOrderTechId(orderTech.getOrderTechId());// 任务单流程赋值给批次流程
      clientBatchMapper.insertBatch(batch);
      BatchFlowFinish batchFlowFinish = new BatchFlowFinish();
      batchFlowFinish.setBatchId(batch.getBatchId());
      batchFlowFinish.setSerialNum(orderFlows.get(0).getSerialNum());
      batchFlowFinish.setStationId(stationId);
      batchFlowFinish.setUserId(userId);
      batchFlowFinish.setStartDate(date);
      batchFlowFinish.setOrderFlowStateId(2);
      batchFlowFinish.setClasseId(classeId);
      batchFlowFinish.setProId(orderFlows.get(0).getProId());
      if(flag){
        /**
         * 一次完工记录报工时间，否则不记录
         * */
        batchFlowFinish.setOrderFlowStateId(3);
        batchFlowFinish.setEndDate(date);
      }
      map.put("barCode",batchCode);
      map.put("batchId",batch.getBatchId());
      map.put("proId",currentOrderFlow.getProId());
      map.put("matId",order.getMatId());
      clientBatchFlowFinishMapper.insertBatchFlowFinish(batchFlowFinish);
      map.put("serialNum",orderFlows.get(0).getSerialNum());
      if(flag){
        map.put("finish",1);
        return JSONObject.build(JSONObject.SUCCESS,batchCode + "创建成功并完工作业",map);
      }else{
        map.put("finish",0);
        return JSONObject.build(JSONObject.SUCCESS,batchCode + "创建成功并开工作业",map);
      }
    }else{
      if(batch.getOrderFlowStateId()>2){
        return JSONObject.build(JSONObject.ERROR,"所有工序都已完工");//3是正常完工，4是跳序完工
      }
      /* *
       * 查询当前工序
       * */
      OrderFlow currentOrderFlow = clientOrderFlowMapper.selectByOrderFlowId(batch.getOrderFlowId());
      List<Integer> orderFlowIdList = new ArrayList<>();
      orderFlowIdList.add(currentOrderFlow.getOrderFlowId());
      List<OrderStation> orderStations = clientOrderStationMapper.selectByOrderFlowIdsAndStationId(orderFlowIdList,stationId);
      if(orderStations.isEmpty()){
        return JSONObject.build(JSONObject.ERROR,batchCode + "批号当前工序为["+currentOrderFlow.getProName()+"]工序不在本工位作业");
      }

      /**
       * 根据当前工序查询下道工序
       * */
      List<OrderFlow> nextOrderFlows = clientOrderFlowMapper.nextOrderFlowByCurrentOrderFlowId(orderFlowIdList.get(0),orderTech.getOrderTechId());

      BatchFlowFinish batchFlowFinish = clientBatchFlowFinishMapper.selectByBatchIdAndSerialNum(batch.getBatchId(),currentOrderFlow.getSerialNum());

      if(nextOrderFlows.isEmpty()){
        batch.setEndClasseDate(classeWork.getLogoutDate());//完工班次时间
        batch.setEndClasseId(classeId);//完工班次
        batch.setEndStationId(stationId);//完工工位
        batch.setFinshDate(date);//完工时间
        batch.setOrderFlowId(currentOrderFlow.getOrderFlowId());
        batch.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
        if(clientBatchMapper.finished(orderId,null) == order.getPlanNum() - 1){ //出自己之外的工序都完工了
          order.setExecuteStateId(5);//1待发布，2已发布，3生产中，4暂停，5完工
          clientOrderMapper.updateOrder(order);
        }
        batch.setProductStateId(4);//1待投产，2投产中，3部分投产，4完工，5报废
      }else{
        batch.setOrderFlowId(nextOrderFlows.get(0).getOrderFlowId());
        batch.setOrderFlowStateId(1);//1未完工，2已投产，3已完工，4跳序完工
        batch.setFinshDate(date);
      }
      batchFlowFinish.setSerialNum(currentOrderFlow.getSerialNum());
      batchFlowFinish.setEndDate(date);
      clientBatchFlowFinishMapper.updateBatchFlowFinish(batchFlowFinish);
      clientBatchMapper.updateBatch(batch);
      map.put("serialNum",currentOrderFlow.getSerialNum());
      map.put("barCode",batchCode);
      map.put("batchId",batch.getBatchId());
      map.put("finish",1);
      map.put("currentOrderFlowId",orderFlowIdArr.get(0));
      map.put("proId",currentOrderFlow.getProId());
      map.put("matId",order.getMatId());
      return JSONObject.build(JSONObject.SUCCESS,batchCode + "批号完工作业",map);
    }
  }

  /**
   *
   * 模式七（一次报工为是）
   */
  private JSONObject sevenJobBook(Integer userId, Integer stationId, Integer orderId, String batchCode, String palletCode,Boolean flag,Boolean isOffLineStation,Integer classeId,ClasseWork classeWork) {
    if(StringUtils.isEmpty(batchCode) || batchCode.equals("null")){
      return JSONObject.build(JSONObject.ERROR,"批号不可为空");
    }
    if(StringUtils.isEmpty(palletCode) || palletCode.equals("null")){
      return JSONObject.build(JSONObject.ERROR,"托盘号不可为空");
    }
    Pallet pallet = clientPalletMapper.selectByPallentCode(palletCode);
    if(pallet.getDataState().equals(3)){
      return JSONObject.build(JSONObject.ERROR, "托盘号已被禁用，不可投产");
    }
    Batch batch = clientBatchMapper.selectByBatchCode(batchCode);
    if(null == batch){
      JSONObject jsonObject = fiveJobBook(userId,stationId,orderId,batchCode,true,isOffLineStation,classeId,classeWork);
      if(jsonObject.getStatus().equals(JSONObject.SUCCESS)){
        Map<String,Object> map = (Map<String, Object>) jsonObject.getData();
        Integer batchId = (Integer) map.get("batchId");
        pallet.setBatchId(batchId);
        clientPalletMapper.updatePallent(pallet);
        jsonObject.setMsg(jsonObject.getMsg()+"(" + palletCode + ")");
      }
      return  jsonObject;
    }else{
      return JSONObject.build(JSONObject.ERROR,"条码已经被使用了");
    }
  }

  /**
   *
   * 模式八（一次报工为否）
   */
  private JSONObject eightJobBook(Integer userId, Integer stationId, Integer orderId, String batchCode, String palletCode, Boolean flag,Boolean isOffLineStation,Integer classeId,ClasseWork classeWork) {

    if(StringUtils.isEmpty(palletCode) || palletCode.equals("null")){
      return JSONObject.build(JSONObject.ERROR,"托盘号不可为空");
    }
    Pallet pallet = clientPalletMapper.selectByPallentCode(palletCode);
    if(pallet.getDataState().equals(3)){
      return JSONObject.build(JSONObject.ERROR, "托盘号已被禁用，不可投产");
    }
    if(null == pallet.getBatchId()){
      if(StringUtils.isEmpty(batchCode) || batchCode.equals("null")){
        return JSONObject.build(JSONObject.ERROR,"请扫描条码");
      }
      JSONObject jsonObject = fiveJobBook(userId,stationId,orderId,batchCode,false,isOffLineStation,classeId,classeWork);
      if(jsonObject.getStatus().equals(JSONObject.SUCCESS)){
        Map<String,Object> map = (Map<String, Object>) jsonObject.getData();
        Integer batchId = (Integer) map.get("batchId");
        pallet.setBatchId(batchId);
        clientPalletMapper.updatePallent(pallet);
        jsonObject.setMsg(jsonObject.getMsg()+"(" + palletCode + ")");
      }
      return  jsonObject;
    }else{
      Batch batch = clientBatchMapper.selectByBatchId(pallet.getBatchId());
      /* *
       * 查询当前工序
       * */
      OrderFlow currentOrderFlow = clientOrderFlowMapper.selectByOrderFlowId(batch.getOrderFlowId());
      List<Integer> orderFlowIds = new ArrayList<>();
      orderFlowIds.add(currentOrderFlow.getOrderFlowId());
      List<OrderStation> orderStations = clientOrderStationMapper.selectByOrderFlowIdsAndStationId(orderFlowIds,stationId);
      if(orderStations.isEmpty()){ //托盘当前绑定的不是首工位
        pallet.setBatchId(null);
        clientPalletMapper.Untying(pallet.getPalletId());
        return JSONObject.build(JSONObject.ERROR,"请扫描条码");
      }else{  //绑定的是本工位
        JSONObject jsonObject = twoJobBook(userId,stationId,orderId,batch.getBatchCode(),true,isOffLineStation,classeId,classeWork);
        jsonObject.setMsg(jsonObject.getMsg()+"("+palletCode+")");
        return jsonObject;
      }
    }
  }


  @Override
  @Transactional
  public JSONObject jobWork(WorkStation workStation) throws Exception {
    String batchCode = workStation.getBatchCode();
    String palletCode = workStation.getPalletCode();
    if(StringUtils.isEmpty(batchCode) && StringUtils.isEmpty(palletCode)){
      return JSONObject.build(JSONObject.ERROR,"托盘号和批号不能同时为空");
    }
    if(!StringUtils.isEmpty(batchCode) && !StringUtils.isEmpty(palletCode)){
      return JSONObject.build(JSONObject.ERROR,"托盘号和批号不能同时存在");
    }
    Batch batch = null;
    if(!StringUtils.isEmpty(batchCode)){
      batch = clientBatchMapper.selectByBatchCode(batchCode);
    }
    if(!StringUtils.isEmpty(palletCode)){
      Pallet pallet = clientPalletMapper.selectByPallentCode(palletCode);
      if(null == pallet){
        return JSONObject.build(JSONObject.ERROR,"没有查到托盘信息");
      }
      if(pallet.getDataState().equals(3)){
        return JSONObject.build(JSONObject.ERROR,"托盘已被禁用");
      }
      if(null == pallet.getBatchId()){
        return JSONObject.build(JSONObject.ERROR,"托盘没有绑定批次信息");
      }
      batch = clientBatchMapper.selectByBatchId(pallet.getBatchId());
    }
    if(null == batch){
      return JSONObject.build(JSONObject.ERROR,"没有查到批次信息");
    }
    Order order = clientOrderMapper.selectByOrderId(batch.getOrderId());

    Map<String,Object> map = new HashedMap();
    map.put("batch",batch);
    map.put("matId",order.getMatId());
    if(batch.getOrderFlowStateId()>2){
      return JSONObject.build(JSONObject.ERROR,"所有工序都已完工",map);
    }
    //当前批次的所有工位
    List<Integer> stationIdList = clientOrderStationMapper.selectStationIdByOrderTechId(batch.getOrderTechId());
    if(!stationIdList.contains(workStation.getStationId())){
      return JSONObject.build(JSONObject.ERROR,"批次流程不包含此工位",map);
    }

    List<Pro> proList = clientProMapper.selectProByOrderTechIdAndStationId(batch.getOrderTechId(),workStation.getStationId());
    if(proList.size()>1){
      StringBuffer sb = new StringBuffer();
      proList.forEach(item -> {
        sb.append(item.getProName());
        sb.append(",");
      });
      return JSONObject.build(JSONObject.ERROR,"此工位不允许对应不同工序[" + sb.toString() + "]",map);
    }
    Classe classe = clientClasseMapper.getById(workStation.getClasseId());
    if(null == classe){
      return JSONObject.build(JSONObject.ERROR, "没有查到班次信息");
    }
    if(classe.getDataState().equals(3)){
      return JSONObject.build(JSONObject.ERROR, "该班次信息被停用了");
    }
    ClasseWork classeWork = clientClasseWorkMapper.onLineByClasseId(workStation.getClasseId());
    if(null ==classeWork){
      return JSONObject.build(JSONObject.ERROR, "该班次没有开工");
    }

    String msg = "";
    Integer finish = 0;
    //查询当前工序
    OrderFlow currentOrderFlow = clientOrderFlowMapper.selectByOrderFlowId(batch.getOrderFlowId());
    //查询当前任务单下，所有剩余工序( 并序完工的也不能查到)
    List<OrderFlow> restOrderFlows = clientOrderFlowMapper.restOrderFlowByOrderTechId(batch.getOrderTechId(),batch.getBatchId());
    Date date = new Date();
    if(order.getActualStartDate() == null) {
      	order.setActualStartDate(date);
     }
    if(null == batch.getProductDate()){
      batch.setProductDate(date);
    }
    batch.setProductStateId(2);//1待投产，2投产中，3部分投产，4完工，5报废
    //当前工序是最后一道流程了
    if(restOrderFlows.size()==1){
      //查询当前工序包含的工位
      List<OrderStation> orderStations = clientOrderStationMapper.selectByOrderFlowIdAndStationId(currentOrderFlow.getOrderFlowId(),workStation.getStationId());
      //当前工序是不是含本工位
      Optional<OrderStation> orderStation = orderStations.stream().filter(item -> item.getStationId().equals(workStation.getStationId())).findFirst();
      if(!orderStation.isPresent()){
        return JSONObject.build(JSONObject.ERROR,"当前工序为最后一道工序[" + currentOrderFlow.getProName() + "]，不包含此工位",map);
      }
      //查看最后一道工序是不是报工了
      BatchFlowFinish batchFlowFinish = clientBatchFlowFinishMapper.selectByBatchIdAndSerialNum(batch.getBatchId(),currentOrderFlow.getSerialNum());
      if(null == batchFlowFinish){ //没有开工
        batchFlowFinish = new BatchFlowFinish();
        batchFlowFinish.setStartDate(date);
        batchFlowFinish.setBatchId(batch.getBatchId());
        batchFlowFinish.setSerialNum(currentOrderFlow.getSerialNum());
        batchFlowFinish.setClasseId(workStation.getClasseId());
        batchFlowFinish.setProId(currentOrderFlow.getProId());
        batchFlowFinish.setUserId(workStation.getUserId());
        batchFlowFinish.setStationId(workStation.getStationId());
        if(workStation.getFlag()){ //一次报工
          batch.setEndClasseDate(classeWork.getLogoutDate());//完工班次时间
          batch.setEndClasseId(workStation.getClasseId());//完工班次
          batch.setEndStationId(workStation.getStationId());//完工工位
          batch.setFinshDate(date);//完工时间
          batch.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
          batchFlowFinish.setEndDate(date);
          batchFlowFinish.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
          batch.setProductStateId(4);//1待投产，2投产中，3部分投产，4完工，5报废
          if(clientBatchMapper.finished(order.getOrderId(),null) == order.getPlanNum() - 1){ //出自己之外的工序都完工了
            order.setExecuteStateId(5);//1待发布，2已发布，3生产中，4暂停，5完工
          }
          msg = "已完工";
          finish = 1;
          // 判断是否为下线工站
          if (workStation.getOffLineStation()) {
            // 判断是否已经插入维修工序
            Integer proTypeId = clientProMapper.queryNextProTypeIdByBatchId(batch.getBatchId());
            if (null != proTypeId && proTypeId == 1) {
              clientAnoService.insertRepair(batch.getBatchId(), batch.getOrderId(), batch.getOrderTechId(), restOrderFlows.get(0).getOrderFlowId(), workStation.getUserId());
            }
          }
        }else{//二次报工
          batch.setOrderFlowStateId(2);//1未完工，2已投产，3已完工，4跳序完工
          batchFlowFinish.setOrderFlowStateId(2);//1未完工，2已投产，3已完工，4跳序完工
          msg = "已开工";
          finish = 0;
        }
        clientBatchFlowFinishMapper.insertBatchFlowFinish(batchFlowFinish);
        batch.setOrderFlowId(currentOrderFlow.getOrderFlowId());
      }else{//开工没完工
        batchFlowFinish.setEndDate(date);
        batchFlowFinish.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
        clientBatchFlowFinishMapper.updateBatchFlowFinish(batchFlowFinish);
        batch.setEndClasseDate(classeWork.getLogoutDate());//完工班次时间
        batch.setEndClasseId(workStation.getClasseId());//完工班次
        batch.setEndStationId(workStation.getStationId());//完工工位
        batch.setFinshDate(date);//完工时间
        batch.setOrderFlowId(currentOrderFlow.getOrderFlowId());
        batch.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
        batch.setProductStateId(4);//1待投产，2投产中，3部分投产，4完工，5报废
        if(clientBatchMapper.finished(order.getOrderId(),null) == order.getPlanNum() - 1){ //出自己之外的工序都完工了
          order.setExecuteStateId(5);//1待发布，2已发布，3生产中，4暂停，5完工
        }
        msg = "已完工";
        finish = 1;
        if (workStation.getOffLineStation()) {
          // 判断是否已经插入维修工序
          Integer proTypeId = clientProMapper.queryNextProTypeIdByBatchId(batch.getBatchId());
          if (null != proTypeId && proTypeId == 1) {
            clientAnoService.insertRepair(batch.getBatchId(), batch.getOrderId(), batch.getOrderTechId(), restOrderFlows.get(0).getOrderFlowId(), workStation.getUserId());
          }
        }
      }
      clientOrderMapper.updateOrder(order);
      map.put("serialNum",currentOrderFlow.getSerialNum());
      clientBatchMapper.updateBatch(batch);
      map.put("finish",finish);
      map.put("currentOrderFlowId",batch.getOrderFlowId());
      map.put("proId",currentOrderFlow.getProId());
      return JSONObject.build(JSONObject.SUCCESS,msg,map);
    }else{ //当前任务单存在未完工的工序
      //剩余工序是否包含此工位
      List<Integer> restOrderFlowIdArr = restOrderFlows.stream().map(OrderFlow :: getOrderFlowId).collect(Collectors.toList());
      List<Integer> restStationIdArr = clientOrderStationMapper.selectStationIdByOrderFlowIdsAndStationId(restOrderFlowIdArr,workStation.getStationId());
      if(restStationIdArr.isEmpty()){
        return JSONObject.build(JSONObject.ERROR,"此工位的工序已经完工,批号当前工序为["+currentOrderFlow.getProName()+"]",map);
      }
      //查询当前工序包含的工位
      List<OrderStation> orderStations = clientOrderStationMapper.selectByOrderFlowIdAndStationId(currentOrderFlow.getOrderFlowId(),workStation.getStationId());
      //当前工序是不是含本工位
      Optional<OrderStation> orderStation = orderStations.stream().filter(item -> item.getStationId().equals(workStation.getStationId())).findFirst();
      //当前工序生产中
      if(batch.getOrderFlowStateId().equals(2)){
        //当前工序生产中  是本工位
        if(orderStation.isPresent()){
          //工位进行报工
          BatchFlowFinish batchFlowFinish = clientBatchFlowFinishMapper.selectByBatchIdAndSerialNum(batch.getBatchId(),currentOrderFlow.getSerialNum());
          batchFlowFinish.setEndDate(date);
          batchFlowFinish.setOrderFlowStateId(3);
          clientBatchFlowFinishMapper.updateBatchFlowFinish(batchFlowFinish);
          batch.setOrderFlowId(restOrderFlowIdArr.get(1));//记录剩余工序的第一道工序
          //剩余工序可能是本工序的并序工序，开工未完工
          BatchFlowFinish flowFinsh = clientBatchFlowFinishMapper.selectByBatchIdAndSerialNum(batch.getBatchId(),restOrderFlows.get(1).getSerialNum());
          if(null == flowFinsh){//下道工序没有进行开工
            batch.setOrderFlowStateId(1);//1未完工，2已投产，3已完工，4跳序完工
          }else{//下道工序进行开工了（这种情况只有是并序工序才存在）
            batch.setOrderFlowStateId(flowFinsh.getOrderFlowStateId());//1未完工，2已投产，3已完工，4跳序完工
          }
          batch.setStationId(workStation.getStationId());
          batch.setUserId(workStation.getUserId());
          batch.setClasseId(workStation.getClasseId());
          clientBatchMapper.updateBatch(batch);
          map.put("currentOrderFlowId",batch.getOrderFlowId());
          map.put("serialNum",currentOrderFlow.getSerialNum());
          map.put("finish",1);
          map.put("proId", currentOrderFlow.getProId());
          if (workStation.getOffLineStation()) {
            // 判断是否已经插入维修工序
            Integer proTypeId = clientProMapper.queryNextProTypeIdByBatchId(batch.getBatchId());
            if (null != proTypeId && proTypeId == 1) {
              clientAnoService.insertRepair(batch.getBatchId(), batch.getOrderId(), batch.getOrderTechId(), batch.getOrderFlowId(), workStation.getUserId());
            }
          }
          return JSONObject.build(JSONObject.SUCCESS,"已完工",map);
        }else{  //当前工序生产中  不是本工位
          //判断当前工序是不是并序
          OrderFlow nowOrderFlow = null;
          if(currentOrderFlow.getSequence()>0){ //是并序
            Integer orderFlowId = 0;//此工位对应的工序
            for(OrderFlow orderFlow: restOrderFlows){
              if(orderFlow.getSequence().equals(currentOrderFlow.getSequence())){
                List<OrderStation> orderStationList = clientOrderStationMapper.selectByOrderFlowIdAndStationId(orderFlow.getOrderFlowId(),workStation.getStationId());
                if(!orderStationList.isEmpty()){
                  orderFlowId  = orderFlow.getOrderFlowId();
                  nowOrderFlow = orderFlow;
                  break;
                }
              }
            }
            if(orderFlowId > 0){ //并序的工序包括这个岗位
              if(null == nowOrderFlow.getOrderFlowStateId()){ //未开工
                BatchFlowFinish batchFlowFinish = new BatchFlowFinish();
                batchFlowFinish.setStartDate(date);
                if(workStation.getFlag()){ //一次完工
                  batchFlowFinish.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
                  batchFlowFinish.setEndDate(date);
                  msg = "已完工";
                  finish = 1;
                }else{ //二次完工
                  batchFlowFinish.setOrderFlowStateId(2);//1未完工，2已投产，3已完工，4跳序完工
                  msg = "已开工";
                  finish = 0;
                }
                batchFlowFinish.setSerialNum(nowOrderFlow.getSerialNum());
                batchFlowFinish.setBatchId(batch.getBatchId());
                batchFlowFinish.setUserId(workStation.getUserId());
                batchFlowFinish.setClasseId(workStation.getClasseId());
                batchFlowFinish.setStationId(workStation.getStationId());
                batchFlowFinish.setProId(currentOrderFlow.getProId());
                clientBatchFlowFinishMapper.insertBatchFlowFinish(batchFlowFinish);
              }else{ //开工未完工
                BatchFlowFinish batchFlowFinish = clientBatchFlowFinishMapper.selectbyBatchFlowFinishId(nowOrderFlow.getBatchFlowFinishId());
                batchFlowFinish.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
                batchFlowFinish.setEndDate(date);
                msg = "已完工";
                finish = 1;
                clientBatchFlowFinishMapper.updateBatchFlowFinish(batchFlowFinish);
              }
              /*
               * 此处需要考虑多线程 加锁，如果此工序进行报工，其并序工序也进行报工，下道工序需要待定
               * */
              map.put("serialNum",orderFlowId);
              map.put("finish",finish);
              map.put("currentOrderFlowId",nowOrderFlow.getOrderFlowId());
              map.put("proId",nowOrderFlow.getProId());
              return JSONObject.build(JSONObject.SUCCESS,msg,map);
            }
          }
          // 当前工序的并序工序 不包括此岗位(或者既不是并序也不是此工位)
            if(workStation.getJump()){ //允许跳序操作
              map = jumpWork(restOrderFlows,batch,workStation,nowOrderFlow,date,order,msg,finish,map,currentOrderFlow,classeWork);
              clientOrderMapper.updateOrder(order);
              return JSONObject.build(JSONObject.SUCCESS,map.get("msg").toString(),map);
            }else{//不允许跳序操作
              return JSONObject.build(JSONObject.ERROR,batch.getBatchCode() + "批号当前工序为["+currentOrderFlow.getProName()+"],不允许跳序完工",map);
            }
        }
      }
      //当前工序应该生产
      if(batch.getOrderFlowStateId().equals(1)){
        //当前工序未开工  是本工位
        if(orderStation.isPresent()){
          //工位进行报工
          BatchFlowFinish batchFlowFinish = new BatchFlowFinish();
          batchFlowFinish.setStartDate(date);
          if(workStation.getFlag()){ //一次完工
            batchFlowFinish.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
            batchFlowFinish.setEndDate(date);
            batch.setOrderFlowId(restOrderFlows.get(1).getOrderFlowId());//记录当前工序的下一道工序
            batch.setOrderFlowStateId(1);//1未完工，2已投产，3已完工，4跳序完工
            msg = "已完工";
            finish = 1;
            if (workStation.getOffLineStation()) {
              // 判断是否已经插入维修工序
              Integer proTypeId = clientProMapper.queryNextProTypeIdByBatchId(batch.getBatchId());
              if (null != proTypeId && proTypeId == 1) {
                clientAnoService.insertRepair(batch.getBatchId(), batch.getOrderId(), batch.getOrderTechId(), batch.getOrderFlowId(), workStation.getUserId());
              }
            }
          }else{ //二次完工
            batchFlowFinish.setOrderFlowStateId(2);//1未完工，2已投产，3已完工，4跳序完工
            batch.setOrderFlowId(currentOrderFlow.getOrderFlowId());
            batch.setOrderFlowStateId(2);//1未完工，2已投产，3已完工，4跳序完工
            msg = "已开工";
            finish = 0;
          }
          batchFlowFinish.setSerialNum(currentOrderFlow.getSerialNum());
          batchFlowFinish.setBatchId(batch.getBatchId());
          batchFlowFinish.setUserId(workStation.getUserId());
          batchFlowFinish.setClasseId(workStation.getClasseId());
          batchFlowFinish.setStationId(workStation.getStationId());
          batchFlowFinish.setProId(currentOrderFlow.getProId());
          clientBatchFlowFinishMapper.insertBatchFlowFinish(batchFlowFinish);
          clientBatchMapper.updateBatch(batch);
          map.put("proId", currentOrderFlow.getProId());
          map.put("currentOrderFlowId",currentOrderFlow.getOrderFlowId());
          map.put("serialNum",currentOrderFlow.getSerialNum());
          clientOrderMapper.updateOrder(order);
          return JSONObject.build(JSONObject.SUCCESS,msg,map);
        }else{ //当前工序未开工， 不是本工位
          //判断当前工序是不是并序
          OrderFlow nowOrderFlow = null;
          if(currentOrderFlow.getSequence()>0) { //是并序
            Integer orderFlowId = 0;//此工位对应的工序
            for(OrderFlow orderFlow: restOrderFlows){
              if(orderFlow.getSequence().equals(currentOrderFlow.getSequence())){
                List<OrderStation> orderStationList = clientOrderStationMapper.selectByOrderFlowIdAndStationId(orderFlow.getOrderFlowId(),workStation.getStationId());
                if(!orderStationList.isEmpty()){
                  orderFlowId  = orderFlow.getOrderFlowId();
                  nowOrderFlow = orderFlow;
                  break;
                }
              }
            }
            if(orderFlowId > 0) { //并序的工序包括这个岗位
              if(null == nowOrderFlow.getOrderFlowStateId()){ //未开工
                BatchFlowFinish batchFlowFinish = new BatchFlowFinish();
                batchFlowFinish.setStartDate(date);
                batchFlowFinish.setSerialNum(nowOrderFlow.getSerialNum());
                if(workStation.getFlag()){ //一次完工
                  batchFlowFinish.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
                  batchFlowFinish.setEndDate(date);
                  msg = "并序已完工";
                  finish = 1;
                }else{ //二次完工
                  batchFlowFinish.setOrderFlowStateId(2);//1未完工，2已投产，3已完工，4跳序完工
                  msg = "并序已开工";
                  finish = 1;
                }
                batchFlowFinish.setBatchId(batch.getBatchId());
                batchFlowFinish.setUserId(workStation.getUserId());
                batchFlowFinish.setClasseId(workStation.getClasseId());
                batchFlowFinish.setStationId(workStation.getStationId());
                batchFlowFinish.setProId(currentOrderFlow.getProId());
                clientBatchFlowFinishMapper.insertBatchFlowFinish(batchFlowFinish);
              }else{ //开工未完工
                BatchFlowFinish batchFlowFinish = clientBatchFlowFinishMapper.selectbyBatchFlowFinishId(nowOrderFlow.getBatchFlowFinishId());
                batchFlowFinish.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
                batchFlowFinish.setEndDate(date);
                msg = "并序已完工";
                finish = 1;
                clientBatchFlowFinishMapper.updateBatchFlowFinish(batchFlowFinish);
              }
              /*
               * 此处需要考虑多线程 加锁，如果此工序进行报工，其并序工序也进行报工，下道工序需要待定
               * */
              map.put("serialNum",nowOrderFlow.getSerialNum());
              map.put("finish",finish);
              map.put("currentOrderFlowId",nowOrderFlow.getOrderFlowId());
              map.put("proId",nowOrderFlow.getProId());
              clientOrderMapper.updateOrder(order);
              return JSONObject.build(JSONObject.SUCCESS,msg,map);
            }
          }
            /* 需要判断是不是维修工序 */
            Pro pro = clientProMapper.selectByProId(currentOrderFlow.getProId());
            if(pro.getProTypeId().equals("3")) { //当前工序是插入维修工序
                //当前工序若果是维修工序需要判断其上道正常工序是否已经完工了
                BatchFlowFinish batchFlowFinish = clientBatchFlowFinishMapper.selectByRepairPro(currentOrderFlow.getSerialNum()-1,batch.getBatchId());
                if(null != batchFlowFinish) {//正常工序开工没完工
                    batchFlowFinish.setEndDate(date);
                    batchFlowFinish.setOrderFlowStateId(3);
                    clientBatchFlowFinishMapper.updateBatchFlowFinish(batchFlowFinish);
//        	          map.put("currentOrderFlowId",currentOrderFlow.getOrderFlowId());
                    map.put("serialNum",currentOrderFlow.getSerialNum()-1);
                    map.put("finish",1);
                    map.put("proId", pro.getProId());
                    return JSONObject.build(JSONObject.SUCCESS,"已完工",map);
                }
            }
          // 当前工序的并序工序 不包括此岗位(或者既不是并序也不是此工位)
            if(workStation.getJump()){ //允许跳序操作
              map = jumpWork(restOrderFlows,batch,workStation,nowOrderFlow,date,order,msg,finish,map,currentOrderFlow,classeWork);
              clientOrderMapper.updateOrder(order);
              return JSONObject.build(JSONObject.SUCCESS,map.get("msg").toString(),map);
            }else{//不允许跳序操作
              return JSONObject.build(JSONObject.ERROR,batch.getBatchCode() + "批号当前工序为["+currentOrderFlow.getProName()+"],不允许跳序完工",map);
            }
        }
      }
      return JSONObject.build(JSONObject.ERROR,"系统出错请联系管理员",map);
    }
  }

  private Map<String,Object> jumpWork(List<OrderFlow> restOrderFlows,Batch batch,WorkStation workStation,OrderFlow nowOrderFlow,Date date,Order order,String msg,Integer finish,Map<String,Object> map,OrderFlow currentOrderFlow,ClasseWork classeWork){
    Integer orderFlowIndex = 0;//此工位对应的工序的下标
    boolean last = false;
    List<BatchFlowFinish> insertBatchFlowFinishList = new ArrayList<>();
    List<BatchFlowFinish> updateBatchFlowFinishList = new ArrayList<>();
    for(int i = 0; i< restOrderFlows.size() ; i++){
      if( null == restOrderFlows.get(i).getBatchFlowFinishId()){ //剩余工序中未开工的
        BatchFlowFinish batchFlowFinish = new BatchFlowFinish();
        batchFlowFinish.setSerialNum(restOrderFlows.get(i).getSerialNum());
        batchFlowFinish.setBatchId(batch.getBatchId());
        batchFlowFinish.setStationId(workStation.getStationId());
        batchFlowFinish.setUserId(workStation.getUserId());
        batchFlowFinish.setClasseId(workStation.getClasseId());
        batchFlowFinish.setProId(currentOrderFlow.getProId());
        batchFlowFinish.setOrderFlowStateId(4);//1未完工，2已投产，3已完工，4跳序完工
        insertBatchFlowFinishList.add(batchFlowFinish);
      }else{    //剩余工序中是存在并序未完工的
        BatchFlowFinish batchFlowFinish = clientBatchFlowFinishMapper.selectbyBatchFlowFinishId(restOrderFlows.get(i).getBatchFlowFinishId()) ;
        batchFlowFinish.setOrderFlowStateId(4);//1未完工，2已投产，3已完工，4跳序完工
        updateBatchFlowFinishList.add(batchFlowFinish);
      }
      //循环工序下面的工位 能不能查到
      List<OrderStation> orderStationList = clientOrderStationMapper.selectByOrderFlowIdAndStationId(restOrderFlows.get(i).getOrderFlowId(),workStation.getStationId());
      if(!orderStationList.isEmpty()){
        orderFlowIndex  = i;
        nowOrderFlow = restOrderFlows.get(i);
        if( i == restOrderFlows.size() - 1){ //如果此工位的工序 是最后一道
          last = true;
        }
        break;
      }
    }
    //此工位的工序是不是并序
    if(nowOrderFlow.getSequence().equals(0) ){ //不是并序
      //修改新增集合的最后一条，
      BatchFlowFinish batchFlowFinish = insertBatchFlowFinishList.get(insertBatchFlowFinishList.size()-1);
      if(workStation.getFlag()){  //一次完工
        batchFlowFinish.setStartDate(date);
        batchFlowFinish.setEndDate(date);
        batchFlowFinish.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
        if(last){ //如果是最后一道工序
          batch.setEndClasseDate(classeWork.getLogoutDate());//完工班次时间
          batch.setEndClasseId(workStation.getClasseId());//完工班次
          batch.setEndStationId(workStation.getStationId());//完工工位
          batch.setFinshDate(date);//完工时间
          batch.setOrderFlowId(nowOrderFlow.getOrderFlowId());
          batch.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
          batch.setProductStateId(4);//1待投产，2投产中，3部分投产，4完工，5报废
          if(clientBatchMapper.finished(order.getOrderId(),null) == order.getPlanNum() - 1){ //出自己之外的工序都完工了
            order.setExecuteStateId(5);//1待发布，2已发布，3生产中，4暂停，5完工
//            clientOrderMapper.updateOrder(order);
          }
          msg = "跳序已完工";
          finish = 1;
        }else{
          batch.setOrderFlowId(restOrderFlows.get(orderFlowIndex + 1).getOrderFlowId()); //记录下次工序的id
          batch.setOrderFlowStateId(1);//1未完工，2已投产，3已完工，4跳序完工
          msg = "跳序已完工";
          finish = 1;
        }
      }else{    //二次完工
        batchFlowFinish.setOrderFlowStateId(2);//1未完工，2已投产，3已完工，4跳序完工
        batchFlowFinish.setStartDate(date);
        batch.setOrderFlowStateId(2);//1未完工，2已投产，3已完工，4跳序完工
        batch.setOrderFlowId(nowOrderFlow.getOrderFlowId());
        msg = "跳序已开工";
        finish = 0;
      }
    }else{ //是并序
      //查询并序的工序集合  升序查询
      List<OrderFlow> sequenceList = clientOrderFlowMapper.selectByOrderTechIdAndSequence(batch.getOrderTechId(),nowOrderFlow.getSequence());
      //将并序的工序筛选掉
      insertBatchFlowFinishList = insertBatchFlowFinishList.stream()
              .filter(item -> !sequenceList.stream()
                      .map(e -> e.getSerialNum())
                      .collect(Collectors.toList())
                      .contains(item.getSerialNum()))
              .collect(Collectors.toList());
      BatchFlowFinish batchFlowFinish = new BatchFlowFinish();
      batchFlowFinish.setStartDate(date);
      batchFlowFinish.setSerialNum(restOrderFlows.get(orderFlowIndex).getSerialNum()); //记录当此工序 顺序号
      batchFlowFinish.setBatchId(batch.getBatchId());
      batchFlowFinish.setStationId(workStation.getStationId());
      batchFlowFinish.setUserId(workStation.getUserId());
      batchFlowFinish.setClasseId(workStation.getClasseId());
      batchFlowFinish.setProId(currentOrderFlow.getProId());
      if(workStation.getFlag()){
        batchFlowFinish.setEndDate(date);
        batchFlowFinish.setOrderFlowStateId(3);//1未完工，2已投产，3已完工，4跳序完工
        batch.setOrderFlowStateId(1); //1未完工，2已投产，3已完工，4跳序完工
        Integer proId = nowOrderFlow.getProId();
        List<OrderFlow> filterSequenceList = sequenceList.stream().filter(s->s.getProId() != proId ).collect(Collectors.toList());
        batch.setOrderFlowId(filterSequenceList.get(0).getOrderFlowId());//记录与当前工序并序的第一道工序
        msg = "并序已完工";
        finish = 1;
      }else{
        batch.setOrderFlowStateId(1); //1未完工，2已投产，3已完工，4跳序完工
        batchFlowFinish.setOrderFlowStateId(2);//1未完工，2已投产，3已完工，4跳序完工
        batch.setOrderFlowId(sequenceList.get(0).getOrderFlowId());//记录与当前工序并序的第一道工序
        msg = "并序已开工";
        finish = 0;
      }
      insertBatchFlowFinishList.add(batchFlowFinish);
    }
    if(!insertBatchFlowFinishList.isEmpty()){
      clientBatchFlowFinishMapper.insertBatchFlowFinishList(insertBatchFlowFinishList);
    }
    if(!updateBatchFlowFinishList.isEmpty()){
      clientBatchFlowFinishMapper.updateBatchFlowFinishList(updateBatchFlowFinishList);
    }
    clientBatchMapper.updateBatch(batch);
    map.put("currentOrderFlowId",restOrderFlows.get(orderFlowIndex).getOrderFlowId());
    map.put("serialNum",nowOrderFlow.getSerialNum());
    map.put("msg",msg);
    map.put("finish",finish);
    map.put("proId",nowOrderFlow.getProId());
    return map;
  }

}
